#ifndef __KERNEL_CUH__
#define __KERNEL_CUH__

#include <stdio.h>
#include "GLee.h"
#include <GL/gl.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glext.h>
#include <GL/glut.h>
#include <Cg/cgGL.h>
#include "cuda-lib.h"
#include <vector_types.h>
#include <vector_functions.h>
#include <cutil.h>
#include <cutil_interop.h>
#include <cuda_gl_interop.h>
#include "flag_parameters.h"

#define STRUCTURAL_SPRING_HORIZONTAL	0
#define STRUCTURAL_SPRING_VERTICAL		1
#define FLEXION_SPRING_HORIZONTAL		2
#define FLEXION_SPRING_VERTICAL		3
#define SHEAR_SPRING_LEFT		4 // The left is  \ 
#define SHEAR_SPRING_RIGHT		5 // The right is /

extern "C" void run_initMasses(pmasse & prev_pos, pmasse & cur_pos, pspring & springs, int width, int height, float pas, GLuint vbo);
extern "C" void run_computeFlag(pmasse & prev, pmasse & cur, pspring & springs, int width, int height, float gravity, float friction, float facteur_l, int dsp, GLuint vbo);
__device__ void setSpring(pmasse mass1, pmasse mass2, int id_mass_opp, spring * ressort, int idx);
cuda_global void initMasses(pmasse prev, pmasse cur, int width, int height, float pas);
cuda_global void initHorStructuralSprings(pspring springs, int offset, int nb_hor_struct_spring, int width, pspring_phys structural_spring_horizontal);
cuda_global void initVertStructuralSprings(pspring springs, int offset, int nb_vert_struct_spring, int width, int height, pspring_phys structural_spring_vertical);
cuda_global void initHorFlexionSprings(pspring springs, int offset, int nb_hor_flex_spring, int width, pspring_phys flexion_spring_horizontal);
cuda_global void initVertFlexionSprings(pspring springs, int offset, int nb_vert_flex_spring, int width, int height, pspring_phys flexion_spring_vertical);
cuda_global void initShearSprings(pspring springs, int offset, int nb_shear_spring, int width, int height, pspring_phys shear_spring_left, pspring_phys shear_spring_right);
cuda_global void computeFlag(pmasse prev, pmasse cur, pspring springs, int width, int nb_springs, float facteur_l, float gravity);
cuda_global void cumul_force(pmasse prev, pmasse cur, int width);
cuda_global void compute_amort(pspring springs, pmasse mass, int width, int nb_springs);
cuda_global void update_mass(pmasse prev, pmasse cur, int width, float gravity, float friction);
cuda_global void adjustment(pspring springs, pmasse cur, int width, int nb_springs, float facteur_l, int physical_spring_type);
cuda_global void cumul_adjust(pmasse mass, int width);
cuda_global void fillVBOshaded(pmasse pos, float3 * vbo_pos, int width);
cuda_global void fillVBOwireframe(pmasse pos, float3 * vbo_pos, int width);
cuda_global void fillVBOsprings(pmasse pos, float3 * vbo_pos, int width);

#endif
